import _ from 'lodash';
import { snippets } from './EventMock';

const ace = window.ace;
const aceRequire = ace.acequire || ace.require;
const snippetManager = aceRequire("ace/snippets").snippetManager;
const Editor = aceRequire("./editor").Editor;
const config = aceRequire("ace/config");

const loadSnippetText = {
  EdcForm: {
    init: function () {
      const { snippetCache } = loadSnippetText.EdcForm;

      if (snippetCache) return Promise.resolve(snippetCache);

      this.snippetCache = snippets;

      return Promise.resolve(snippets);
    },
    snippetCache: null,
    snippets: ""
  }
};

export const snippetScopces = function () {
  const parseSnippets = function (snippets) {
    snippets = (snippets || []).map(function (snippet, index) {

      const snippetTextObj = {
        content: snippet.snippet,
        snippet: snippet.snippetFace,
        name: snippet.snippetFace,
        layout: snippet.noteContent,
        title: snippet.noteTitle
      };

      return snippetTextObj;
    });

    return snippets;
  };

  snippetManager.files = {} || snippetManager.files;

  const loadSnippetFile = function (id) {
    if (!id || snippetManager.files[id]) return;

    let snippetFilePath = id.replace("mode", "snippets"),
      mode = id.replace(/.*\/(.*)$/g, "$1");
    snippetManager.files[id] = {};

    config.loadModule(snippetFilePath, function (mod) {
      if (!mod) return;

      snippetManager.files[id] = mod;
      if (!mod.snippets && mod.snippetText) {
        if (loadSnippetText[mode]) {
          mod.snippets = loadSnippetText[mode].snippets;
        } else {
          mod.snippets = snippetManager.parseSnippetFile(mod.snippetText);
        }
      }

      snippetManager.register(mod.snippets || [], mode);

      if (mod.includeScopes) {
        snippetManager.snippetMap[mod.scope].includeScopes = mod.includeScopes;
        mod.includeScopes.forEach(function (x) {
          loadSnippetFile("ace/mode/" + x);
        });
      }
    });
  };

  config.defineOptions(Editor.prototype, "editor", {
    includeScopes: { // 设置依赖mode
      set: function (modes) {
        if (!_.isArray(modes)) return;

        modes.forEach(mode => {
          if (!loadSnippetText[mode]) {
            loadSnippetFile("ace/mode/" + mode);
          } else {
            // 异步加载关键字列表
            loadSnippetText[mode].init().then(function (snippets) {
              loadSnippetText[mode].snippets = parseSnippets(snippets);
              loadSnippetFile("ace/mode/" + mode);
            });
          }
        });
      },
      value: []
    }
  });
}

export const EdcForm_completer = function () {
  return {
    getCompletions: function (editor, session, pos, prefix, callback, autocomplete) {
      const snippetMap = snippetManager.snippetMap;
      let completions = [];
      let isMobNS = false, identifier;
      const state = editor.session.getState(pos.row);
      // 获取是否与mode的关键字匹配 如果没有匹配 说明当前输入的上下文中不允许输入js
      const keyCompletions = session.$mode.getCompletions(state, session, pos, prefix).length;
      const includeScopes = editor.$includeScopes || [];

      if (!keyCompletions || !~includeScopes.indexOf("EdcForm")) return callback(null, completions);

      this.identifier.every(function (ident) {
        if (ident == prefix.slice(0, ident.length)) {
          isMobNS = true;
          identifier = ident;
          return false;
        }
        return true;
      });

      const snippets = snippetMap.EdcForm || [];

      for (let i = snippets.length; i--;) {
        let s = snippets[i],
          isMatch = s.content.toLowerCase().indexOf(prefix.toLowerCase()) != -1 && prefix.indexOf(identifier) != -1,
          caption = s.name || s.tabTrigger;

        if (!caption || !isMobNS) continue;

        const snippetCompletionObj = {
          value: isMatch ? identifier + caption : '', // filter会首先根据去value的值 否则caption
          caption: caption,
          title: s.title,
          snippet: s.content,
          meta: s.tabTrigger && !s.name ? s.tabTrigger + "\u21E5 " : "snippet",
          type: "snippet",
          layout: s.layout
        };

        completions.push(snippetCompletionObj);
      }

      if (isMobNS && autocomplete) {
        autocomplete.base = session.doc.createAnchor(pos.row, pos.column - prefix.length + identifier.length);
      }

      callback(null, completions);
    },
    getDocTooltip: function (item) {
      if (item.layout) {
        item.docHTML = [
          "<b>", item.title, "</b>", "<hr></hr>", item.layout
        ].join("");
      }
    },
    identifierRegexps: [/[a-zA-Z_\.\\$]/],
    identifier: ['EdcForm.']
  };
}